package com.kexio.enterprise.observability.tracing;

import com.kexio.enterprise.observability.tracing.context.TraceContext;
import com.kexio.enterprise.observability.tracing.domain.TraceInfo;
import com.kexio.enterprise.observability.tracing.enums.SpanStatus;
import com.kexio.enterprise.observability.tracing.query.TracingQueryCriteria;
import com.kexio.enterprise.observability.tracing.statistics.TracingStatistics;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 链路追踪服务接口
 * 
 * 提供分布式系统的链路追踪功能
 * 
 * @author Kexio
 * @since 1.0.0
 */
public interface TracingService {

    /**
     * 开始一个新的追踪
     * 
     * @param operationName 操作名称
     * @return 追踪上下文
     */
    TraceContext startTrace(String operationName);

    /**
     * 开始一个子span
     * 
     * @param parentContext 父追踪上下文
     * @param operationName 操作名称
     * @return 子追踪上下文
     */
    TraceContext startSpan(TraceContext parentContext, String operationName);

    /**
     * 完成当前span
     * 
     * @param context 追踪上下文
     */
    void finishSpan(TraceContext context);

    /**
     * 添加标签
     * 
     * @param context 追踪上下文
     * @param key     标签键
     * @param value   标签值
     */
    void addTag(TraceContext context, String key, String value);

    /**
     * 添加多个标签
     * 
     * @param context 追踪上下文
     * @param tags    标签映射
     */
    void addTags(TraceContext context, Map<String, String> tags);

    /**
     * 添加日志
     * 
     * @param context 追踪上下文
     * @param message 日志消息
     */
    void addLog(TraceContext context, String message);

    /**
     * 添加结构化日志
     * 
     * @param context 追踪上下文
     * @param fields  日志字段
     */
    void addLog(TraceContext context, Map<String, Object> fields);

    /**
     * 记录异常
     * 
     * @param context   追踪上下文
     * @param exception 异常
     */
    void recordException(TraceContext context, Throwable exception);

    /**
     * 设置span状态
     * 
     * @param context 追踪上下文
     * @param status  状态
     */
    void setSpanStatus(TraceContext context, SpanStatus status);

    /**
     * 获取当前追踪上下文
     * 
     * @return 当前追踪上下文
     */
    TraceContext getCurrentContext();

    /**
     * 设置当前追踪上下文
     * 
     * @param context 追踪上下文
     */
    void setCurrentContext(TraceContext context);

    /**
     * 从Header中提取追踪上下文
     * 
     * @param headers HTTP头
     * @return 追踪上下文
     */
    TraceContext extractContext(Map<String, String> headers);

    /**
     * 将追踪上下文注入到Header中
     * 
     * @param context 追踪上下文
     * @param headers HTTP头
     */
    void injectContext(TraceContext context, Map<String, String> headers);

    /**
     * 获取追踪信息
     * 
     * @param traceId 追踪ID
     * @return 追踪信息
     */
    TraceInfo getTraceInfo(String traceId);

    /**
     * 查询追踪信息
     * 
     * @param criteria 查询条件
     * @return 追踪信息列表
     */
    List<TraceInfo> queryTraces(TracingQueryCriteria criteria);

    /**
     * 获取追踪统计
     * 
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 追踪统计
     */
    TracingStatistics getTracingStatistics(LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 清空追踪数据
     */
    void clearTraces();

    /**
     * 启用/禁用追踪
     * 
     * @param enabled 是否启用
     */
    void setTracingEnabled(boolean enabled);
}
